package cn.stylefeng.guns.sys.modular.system.service.impl;

import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.core.util.DingdingAttendUtil;
import cn.stylefeng.guns.sys.core.util.DingdingUtil;
import cn.stylefeng.guns.sys.core.util.TimeUtil;
import cn.stylefeng.guns.sys.core.util.UUIDUtils;
import cn.stylefeng.guns.sys.modular.system.entity.BtyDingdingDayDept;
import cn.stylefeng.guns.sys.modular.system.entity.BtyDingdingDayEmp;
import cn.stylefeng.guns.sys.modular.system.mapper.BtyDingdingDayEmpMapper;
import cn.stylefeng.guns.sys.modular.system.model.params.BtyDingdingDayDeptParam;
import cn.stylefeng.guns.sys.modular.system.model.params.BtyDingdingDayEmpParam;
import cn.stylefeng.guns.sys.modular.system.model.result.BtyDingdingDayEmpResult;
import cn.stylefeng.guns.sys.modular.system.service.BtyDingdingDayDeptService;
import  cn.stylefeng.guns.sys.modular.system.service.BtyDingdingDayEmpService;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dingtalk.api.response.OapiUserSimplelistResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;

/**
 * <p>
 * 钉钉,最新,员工,记录 服务实现类
 * </p>
 *
 * @author wjk
 * @since 2022-05-30
 */
@Service
public class BtyDingdingDayEmpServiceImpl extends ServiceImpl<BtyDingdingDayEmpMapper, BtyDingdingDayEmp> implements BtyDingdingDayEmpService {


    private static Logger logger = LoggerFactory.getLogger(BtyDingdingDayEmpServiceImpl.class);

    @Resource
    private DingdingAttendUtil dingdingAttendUtil;

    @Autowired
    private BtyDingdingDayDeptService btyDingdingDayDeptService;

    @Override
    public void add(BtyDingdingDayEmpParam param){
        BtyDingdingDayEmp entity = getEntity(param);
        this.save(entity);
    }

    @Override
    public void delete(BtyDingdingDayEmpParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(BtyDingdingDayEmpParam param){
        BtyDingdingDayEmp oldEntity = getOldEntity(param);
        BtyDingdingDayEmp newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public BtyDingdingDayEmpResult findBySpec(BtyDingdingDayEmpParam param){
        return null;
    }

    @Override
    public List<BtyDingdingDayEmpResult> findListBySpec(BtyDingdingDayEmpParam param){
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(BtyDingdingDayEmpParam param){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }






    private Serializable getKey(BtyDingdingDayEmpParam param){
        return param.getId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private BtyDingdingDayEmp getOldEntity(BtyDingdingDayEmpParam param) {
        return this.getById(getKey(param));
    }

    private BtyDingdingDayEmp getEntity(BtyDingdingDayEmpParam param) {
        BtyDingdingDayEmp entity = new BtyDingdingDayEmp();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }



    /**
     * 开始同步半天妖部门的员工信息
     * 月度
     * @author
     * @Date 2022-04-14
     * 钉钉 写成定时任务；
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, String> addBtyDingdingMonthEmp(BtyDingdingDayEmpParam param) throws InterruptedException {
        String  lastMonth = param.getAttendYearMonth();
        if(ToolUtil.isEmpty(param.getAttendYearMonth())){
            // 若没有传参数，则默认上月月的数据
            lastMonth  = TimeUtil.getLastMonthStr();
        }
        BtyDingdingDayDeptParam BtyDingdingDayDeptParam = new BtyDingdingDayDeptParam();
        BtyDingdingDayDeptParam.setAttendYearMonth(lastMonth);


        // 获取半天妖所有的部门列表（所有）
        List<BtyDingdingDayDept> BtyDingdingDayDeptList = btyDingdingDayDeptService.listMonthAll(BtyDingdingDayDeptParam);

        // 根据部门，获取员工的列表，
        List<BtyDingdingDayEmp> emplist = new ArrayList<BtyDingdingDayEmp>();
        // 循环部门信息，获取员工列表
        logger.info("获取部门员工数据-预计3分钟，耐心等待......");
        for(BtyDingdingDayDept dept:BtyDingdingDayDeptList){
            List<Map<String,Object>> rslist=new LinkedList<>();
            boolean hasMore= false;
            Long offset = 0L;
            Long size = 100L;

            do{
                OapiUserSimplelistResponse rsp = dingdingAttendUtil.getEmpList(dept.getDid(),offset,size);
                Map map=(Map) JSON.parse(rsp.getBody());
                Integer errcode=(Integer) map.get("errcode");
                List list=(List) map.get("userlist");
                hasMore= (boolean) map.get("hasMore");
                offset += size;
                rslist.addAll(list);
                //logger.info("获取部门数据，部门：{}，员工：{}",dept.getName(),list.size());
            }while(hasMore);


            // 将员工数据进行处理，
            for (Map<String,Object> mapRs : rslist){
                BtyDingdingDayEmp emp=new BtyDingdingDayEmp();
                emp.setId(UUIDUtils.getId());
                emp.setAttendYearMonth(lastMonth);
                emp.setEmpId(String.valueOf(mapRs.get("userid")));
                emp.setEmpName(String.valueOf(mapRs.get("name")));
                emp.setDeptId(dept.getDid());
                emp.setDeptName(dept.getName());
                emp.setEmpPhone(String.valueOf(mapRs.get("mobile")));
                emplist.add(emp);
            }
            Thread.sleep(10);
        }

        // 根据月份，去删除数据当月的员工数据
        Integer delSize = this.baseMapper.deleteByYearMonth(lastMonth);
        // 将员工数据存入数据库中
        simpleSqlInsertBatch(emplist);
        // 返回存入的数据
        Map<String, String> mapResult = new HashMap<>();
        mapResult.put("size",String.valueOf(emplist.size()));
        return mapResult;
    }

    /**
     * 获取半天妖所有的人员列表（所有）
     * 根据月份
     * @param param
     * @return
     */
    @Override
    public List<BtyDingdingDayEmp> listMonthAll(BtyDingdingDayEmpParam param) {
        LambdaQueryWrapper<BtyDingdingDayEmp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BtyDingdingDayEmp::getAttendYearMonth,  param.getAttendYearMonth());
        List<BtyDingdingDayEmp> list = this.list(queryWrapper);
        return list;
    }

    /**
     * 获取半天妖所有的人员列表（所有不重复数据）
     * @param param
     * @return
     */
    @Override
    public List<BtyDingdingDayEmp> listMonthAllNotRepeat(BtyDingdingDayEmpParam param) {
        List<BtyDingdingDayEmp> list = this.baseMapper.listMonthAllNotRepeat(param);
        return list;
    }

    public int simpleSqlInsertBatch(List<BtyDingdingDayEmp> list) {
        if (list == null || list.size() < 1) {
            return 0;
        }
        // 如果提交的列表条数小于提交阀值
        List<BtyDingdingDayEmp>[] splitLists = splitLists(list, 200);
        for (List<BtyDingdingDayEmp> tempList : splitLists) {
            this.baseMapper.addList(tempList);
            //this.saveBatch(tempList);
        }
        return list.size();
    }

    /**
     * 对一个列表按照splitNum进行分割。
     *
     * @param lists
     * @param splitNum
     * @param <T>
     * @return
     */
    public static <T>List<BtyDingdingDayEmp>[] splitLists(List<BtyDingdingDayEmp> lists, int splitNum) {
        int listSize;
        if (lists == null || (listSize = lists.size()) < 1) {
            return new ArrayList[0];
        }
        int length = listSize % splitNum == 0 ? listSize / splitNum : listSize / splitNum + 1;
        // 这里面如果用ArrayList，会在50行报错。ArrayList list = new List();这样会报错。
        List<BtyDingdingDayEmp>[] results = new List[length];
        int fromIndex, toIndex;
        for (int i = 0; i < length; i++) {
            fromIndex = i * splitNum;
            toIndex = (fromIndex + splitNum) > listSize ? listSize : (fromIndex + splitNum);
            results[i] = lists.subList(fromIndex, toIndex);
        }
        return results;
    }
}
